
## Enables easy access to all classes
push(@INC, "..");
push(@INC, "../Managers");
push(@INC, "../MapLoaders");
push(@INC, "Tests");


### VSTF
### Very simple (automated) testing framework
### TEST:
### Main class: Process test according to parameters


package Test;

sub create{
    my $class = shift;
    my $obj = {};
    bless $obj, $class;
    $obj->Test::init(@_);
    $obj->init(@_) unless $class == "Test";
    return $obj
}


sub init{
    my $self = shift;
    
    $self->{VARIABLES} = {};

    # To be assigned by the test launcher
    # Used to store auxiliary components
    # During set-up and tear-down of tests
    # Should be a hash reference
    $self->{CONTAINER} = undef;

    # Can be:
    #  OK
    #  ERROR
    #  CRITICAL
    #
    # If at the end of the test, the status is CRITICAL,
    # the whole process is automatically aborted
    $self->{STATUS} = "OK";

}

# Prepare the test
sub setup{
}

# Execute the test
sub run{
    my $self = shift;

    $self->setVar("TESTVAR_Y", 1);
    $self->setVar("TESTVAR_N", 0);
}

# Clean up temporary values
sub teardown{
}

sub setVar{
    my $self = shift;
    my $v_name = shift;
    my $v_val = shift;

    $self->{VARIABLES}->{$v_name} = $v_val;
}

sub vars{
    my $self = shift;
    return %{$self->{VARIABLES}};
}

sub component{
    my ($self, $key) = (shift, shift);
    my $newval = shift;
    my $oldval= $self->{CONTAINER}->{$key};
    $self->{CONTAINER}->{$key} = $newval if(defined($newval));
    return $oldval;
}


sub evaluate{
    my $self = shift;
    my $code = shift;

    $self->log("Evaluating: ".$code);
    my $result = eval $code;
    $self->log("    Result: ".$result);
    return $result;
}

sub log{
    my $self = shift;
    my $msg = shift;

    print $msg;
    print "\n";
}


## If value == expected, set the variable VAR to 1
## Otherwise, set to 0
## The status of the test is set to ERROR or CRITICAL, according to the parameter "weight"
sub assertEq{
    my $self = shift;
    my ($value, $expected, $variable_name) = (shift, shift, shift);
    my $weight = shift;
    
    if($value eq $expected){
	$self->{VARIABLES}->{$variable_name} = 1;
    }else{
	$self->log("ERROR: Expecting ".$expected."; Found ".$value);
	$self->{VARIABLES}->{$variable_name} = 0;

	$self->{STATUS} = "ERROR";
	$self->{STATUS} = "CRITICAL" if $weight eq "CRITICAL";
    }
}

## If value == expected, set the variable VAR to 1
## Otherwise, set to 0
sub assertNEq{
    my $self = shift;
    my ($value, $expected, $variable_name) = (shift, shift, shift);
    my $weight = shift;

    if($value ne $expected){
	$self->{VARIABLES}->{$variable_name} = 1;
    }else{
	$self->log("ERROR: Found ".$value."; Expected different");
	$self->{VARIABLES}->{$variable_name} = 0;
	$self->{STATUS} = "ERROR";
	$self->{STATUS} = "CRITICAL" if $weight eq "CRITICAL";
    }
}


## Shortcut to assertEq($var, 1, $varname)
sub assertTrue{
    my $self = shift;
    my ($value, $variable_name) = (shift, shift, shift);
    my $weight = shift;

    $self->assertEq($value, 1, $variable_name);
}

## Shortcut to assertNeq($var, 1, $varname)
sub assertFalse{
    my $self = shift;
    my ($value, $variable_name) = (shift, shift, shift);
    my $weight = shift;

    $self->assertNEq($value, 1, $variable_name);
}

## Stores something in the container
sub store{
    my $self = shift;
    my $container = $self->{CONTAINER};
    my ($key, $val) = (shift, shift);
    $container->{$key} = $val;
}

1;
